package com.app;


import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.Application;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Debug;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;

import com.app.util.Utils;

import org.apache.http.HttpResponse;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


public class AppException extends Exception implements UncaughtExceptionHandler{

	
	private String TAG = AppException.class.getSimpleName();
		
	
	Activity activity ;
	Context context ;

	Thread 	thread;
	Throwable ex;


		
	/** 系统默认的UncaughtException处理类 */
	private UncaughtExceptionHandler mDefaultHandler;
	
	private AppException(){
		this.mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
	}
	
	/**
	 * 获取APP异常崩溃处理对象
	 * @param context
	 * @return
	 */
	public static AppException getAppExceptionHandler(){
		return new AppException();
	}
		
		
		
	@Override
	public void uncaughtException(Thread thread, Throwable ex) {
		// TODO Auto-generated method stub
		
		this.thread = thread;
		this.ex = ex;
		Log.d(TAG, "======================================app catch exception");
		
		
		if(!handleException(ex) && mDefaultHandler != null) {  // 如果没有处理，由系统处理
			mDefaultHandler.uncaughtException(thread, ex);
		}
		
	
	}
	
	private boolean handleException(Throwable ex){
		
		activity = AppManager.getAppManager().currentActivity();
		System.out.println("cur_activity: "+activity);
		
		
		if(activity == null)
			return false;
		
		
		context = activity;
	//	context = CustomApplication.getInstance().getApplicationContext(); //
		
		
		final String crash_content =getCrashReport(context, ex);
		final String CarshFile = saveErrorLog(this);	
		
		Log.e(TAG, "crash_content: "+ crash_content);
		
		
		

		boolean bSendError = false;
		if(bSendError){
			
			/*
			new Thread() {
				public void run() {
					Looper.prepare();	// 有消息队列，使handler可用
					AlertDialog(crash_content); // requestNetData_sendAppCrashReport(carsh_content); //
					Looper.loop();
				}
	
			}.start();
			*/
			
			/*
			new Thread() {
				public void run() {
					Looper.prepare();
					String title = AppConfig.PACK_NAME + " - 错误报告";
					Utils.sendAppCrashReport(context, title, crash_content);
					Looper.loop();
				}
	
			}.start();
			*/

			///* 使用该处
			new Thread() {
				public void run() {
					Looper.prepare();
					String title = G.PACK_NAME + " - 错误报告";
					requestNetData_sendAppCrashReport(crash_content); 
					Looper.loop();
				}
	
			}.start();
			//*/

			
			//Umeng.reportError(context, ex);
			
		}
		else{
		
		
			
			return false;
		}
		
		
//		restartApp();
		
		System.out.println("CarshFile: " + CarshFile);
		
		return true;
	}
	
	
	public void restartApp(){
		
		AppManager.getAppManager().finishAllActivity();

		/*
    	Intent intent = new Intent(context, LoginActivity.class);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		context.startActivity(intent);
		*/
		
		android.os.Process.killProcess(android.os.Process.myPid());  //结束进程之前可以把你程序的注销或者退出代码放在这段代码之前
    }
	
	
	void AlertDialog(final String content){
		
		
		try{
		 Dialog AlertDialog = new AlertDialog.Builder(context). 
	             //   setTitle( context.getResources().getString(R.string.crash_title) ). 
	                setMessage( "出错了" ). 
	            //    setIcon(R.drawable.ic_launcher). 
	                setCancelable(false).
	                setPositiveButton("确定", new DialogInterface.OnClickListener() { 
	                     
	                    @Override 
	                    public void onClick(DialogInterface dialog, int which) { 
	                        // TODO Auto-generated method stub  
	                    	
	                    	requestNetData_sendAppCrashReport(content);
	                    	
	                    } 
	                }). 
	                /*
	                setNegativeButton("取消", new DialogInterface.OnClickListener() { 
	                     
	                    @Override 
	                    public void onClick(DialogInterface dialog, int which) { 
	                        // TODO Auto-generated method stub  
	                    } 
	                }). 
	                setNeutralButton("查看详情", new DialogInterface.OnClickListener() { 
	                     
	                    @Override 
	                    public void onClick(DialogInterface dialog, int which) { 
	                        // TODO Auto-generated method stub  
	                    } 
	                }).
	                */ 
	                create(); 
	        AlertDialog.show(); 
		}
		catch(Exception e){
			e.printStackTrace();
			
			System.out.println("=============report Dialog exception");
			// 
			requestNetData_sendAppCrashReport(content);
			
		}
		
	     
		
	}  
	
	
	
	 
	
	private void requestNetData_sendAppCrashReport( final String content){
	    /*
        new NetHelper(context) {

			@Override
			public String init(ArrayList<BasicNameValuePair> map) {
				// TODO Auto-generated method stub

				String str = getRunningAppProcessInfo();

				map.add(new BasicNameValuePair("userId", "") );
				map.add(new BasicNameValuePair("userName", UserServer.getUserName(activity)) );
				map.add(new BasicNameValuePair("content", content + "\n" + str) );
				

				String url = ApiConfig.SERVER_PAY_HOST + ApiConfig.SERVER_PAY_API.log_post;
				return url;
			}
		
			
			public void thread_onComplete(String message) throws JSONException {
				
				System.out.println("thread_onComplete");
			
				JSONObject obj = new JSONObject(message);
				if(obj.getString("result").equals("0")){ //提交成功
					System.out.println("错误报告发送成功");
					 
				}
				else{
					System.out.println("错误报告发送失败");
				}
				
				restartApp();
				
			};
			
			
			@Override
			public void onComplete(String message) throws JSONException {
				// TODO Auto-generated method stub
				
				System.out.println("onComplete");
				
			}
			
			public void thread_onError(String StatusCode) {
				
				restartApp();
			};
			
			
			
		}.start_POST();
		*/
        
	}


	private String getRunningAppProcessInfo() {
		ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

		//获得系统里正在运行的所有进程
		List<ActivityManager.RunningAppProcessInfo> runningAppProcessesList = mActivityManager.getRunningAppProcesses();

		for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcessesList) {
			// 进程ID号
			int pid = runningAppProcessInfo.pid;
			// 用户ID
			int uid = runningAppProcessInfo.uid;
			// 进程名
			String processName = runningAppProcessInfo.processName;
			// 占用的内存
			if(processName.equals(context.getPackageName())){
				int[] pids = new int[] {pid};
				Debug.MemoryInfo[] memoryInfo = mActivityManager.getProcessMemoryInfo(pids);
				int memorySize = memoryInfo[0].dalvikPrivateDirty;


				return "processName="+processName+"memorySize="+memorySize+"kb";

			}



		}
		return "";

	}

	
	
	
	private String httpPostHelper( String url, ArrayList<BasicNameValuePair> parameters ) {
		String jsonString = "";
		try {
			

			HttpPost post = new HttpPost(url);
			BasicHttpParams httpParams = new BasicHttpParams();
			HttpConnectionParams.setConnectionTimeout(httpParams, 500);
			HttpConnectionParams.setSoTimeout(httpParams, 500);
			post.setEntity(new UrlEncodedFormEntity(parameters, HTTP.UTF_8));
			HttpResponse response = new DefaultHttpClient(httpParams)
					.execute(post);

			int StatusCode = response.getStatusLine().getStatusCode();

			if (StatusCode == 200)
				jsonString = EntityUtils
						.toString(response.getEntity(), "UTF-8");
			else{
			}

			System.out.println("提交异常返回: "+jsonString);
			return jsonString;

		} catch (Exception e) {
			e.printStackTrace();
			return jsonString;
		}

	}
	
	/*
	// 超时问题
	private String httpPostHelper(String url, ArrayList<BasicNameValuePair> parameters) {
		String jsonString = "";
		try {

			HttpPost post = new HttpPost(url);
			BasicHttpParams httpParams = new BasicHttpParams();
			HttpConnectionParams.setConnectionTimeout(httpParams, 1000);
			HttpConnectionParams.setSoTimeout(httpParams, 500);
			post.setEntity(new UrlEncodedFormEntity(parameters, HTTP.UTF_8));
			
		//	DefaultHttpClient httpclient = new DefaultHttpClient(); //设置本地为客户端
	    //    httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 500);//请求超时
	    //    httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 500); //读取超时
	    //    HttpResponse response = httpclient.execute(post);
	         
			HttpResponse response = new DefaultHttpClient(httpParams)
					.execute(post);
			int StatusCode = response.getStatusLine().getStatusCode();

			if (StatusCode == 200)
				jsonString = EntityUtils
						.toString(response.getEntity(), "UTF-8");
			else{
				//thread_onError(""+StatusCode);
			}
			
			System.out.println("------------"+jsonString);

			return jsonString;

		} catch (Exception e) {
			e.printStackTrace();
			return jsonString;
		}

	}
	*/
	
	
	
	void restart(){
		
		
		/*
		AppManager.getAppManager().finishAllActivity();
		System.exit(1);
		*/
		
        /*
	    int currentVersion = android.os.Build.VERSION.SDK_INT;  
        if (currentVersion > android.os.Build.VERSION_CODES.ECLAIR_MR1) {  
            Intent startMain = new Intent(Intent.ACTION_MAIN);  
            startMain.addCategory(Intent.CATEGORY_HOME);  
            startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
            activity.startActivity(startMain);  
            System.exit(0);  
        } else {// android2.1  
            ActivityManager am = (ActivityManager) activity.getSystemService( activity.ACTIVITY_SERVICE );  
            am.restartPackage( Config.PACK_NAME );  
        }  
        */
		
		
	  

//		mDefaultHandler.uncaughtException(thread, ex);
		
		

		
	}
	
	
	
	/**
	 * 获取APP崩溃异常报告
	 * @param ex
	 * @return
	 */
	private String getCrashReport(Context context, Throwable ex) {
		
		if(context != null){
		
			Application ca =(Application)context.getApplicationContext();
			PackageInfo pinfo = getPackageInfo(context);
			StringBuffer exceptionStr = new StringBuffer(); 
			exceptionStr.append(("*************"+(Utils.getNowTime1())+"*************\n"));
			exceptionStr.append("Version: "+pinfo.versionName+"("+pinfo.versionCode+")\n");
			exceptionStr.append("Android: "+android.os.Build.VERSION.RELEASE+"("+android.os.Build.MODEL+")\n");
			exceptionStr.append("Exception: "+ex.getMessage()+"\n");
			StackTraceElement[] elements = ex.getStackTrace();
			for (int i = 0; i < elements.length; i++) {
				exceptionStr.append(elements[i].toString()+"\n");
			}
			return exceptionStr.toString();
		}
		else{
			StringBuffer exceptionStr = new StringBuffer(); 
			exceptionStr.append(("--------------------"+(Utils.getNowTime1())+"--------------------\n"));
			exceptionStr.append("Android: "+android.os.Build.VERSION.RELEASE+"("+android.os.Build.MODEL+")\n");
			exceptionStr.append("Exception: "+ex.getMessage()+"\n");
			StackTraceElement[] elements = ex.getStackTrace();
			for (int i = 0; i < elements.length; i++) {
				exceptionStr.append(elements[i].toString()+"\n");
			}
			
			
			System.exit(0);
			
			return exceptionStr.toString();
		}
		
	
	}


	/**
	 * 获取App安装包信息
	 *
	 * @return
	 */
	private PackageInfo getPackageInfo(Context context) {
		PackageInfo info = null;
		try {
			info = context.getPackageManager().getPackageInfo(
					context.getPackageName(), 0);
		} catch (PackageManager.NameNotFoundException e) {
			e.printStackTrace(System.err);
		}
		if (info == null)
			info = new PackageInfo();
		return info;
	}

	
	// try catch final 解释相关:http://hi.baidu.com/jt763844132/item/15bd1efa8a27f0c6531c26d7
	/**
	 * 保存异常日志
	 * @param excp
	 */
	public String saveErrorLog(Exception excp) {
		String errorlog = "errorLog.txt";
		String savePath = "";
		String logFilePath = "";
		FileWriter fw = null;
		PrintWriter pw = null;
		
		
		//    "MYSKILLS"
		try {
			//判断是否挂载了SD卡
			String storageState = Environment.getExternalStorageState();		
			if(storageState.equals(Environment.MEDIA_MOUNTED)){
				savePath = Environment.getExternalStorageDirectory().getAbsolutePath() ;
				savePath +=  "/" + G.PACK_NAME + "/";
				File file = new File(savePath);
				if(!file.exists()){
					file.mkdirs();
				}
				logFilePath = savePath + errorlog;
			}
			//没有挂载SD卡，无法写文件
			if(logFilePath == ""){
				logFilePath = activity.getFilesDir() + G.PACK_NAME + "/";
			}
			File logFile = new File(logFilePath);
			if (!logFile.exists()) {
				logFile.createNewFile();
			}
			fw = new FileWriter(logFile,false);  // 不使用append模式,log文件会积累的太多
			pw = new PrintWriter(fw);
			pw.println("--------------------"+(new Date().toLocaleString())+"---------------------");	
			excp.printStackTrace(pw);
			pw.close();
			fw.close();
		} catch (Exception e) {
			e.printStackTrace();		
		}finally{ 
			if(pw != null){ pw.close(); } 
			if(fw != null){ try { fw.close(); } catch (IOException e) { }}
			
			return logFilePath;
		}
		
	
		

	}
	
	
	
	
}




/* Throwable中出来的
	Version: 1.0(1)
	Android: 2.3.6(Seals TS3)
	Exception: divide by zero
	com.example.skills.CrashActivity$1.onClick(CrashActivity.java:38)
	com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:191)
	android.os.Handler.dispatchMessage(Handler.java:130)
	android.os.Looper.loop(SourceFile:351)
	android.app.ActivityThread.main(ActivityThread.java:3814)
	java.lang.reflect.Method.invokeNative(Native Method)
	java.lang.reflect.Method.invoke(Method.java:538)
	com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
	com.android.internal.os.ZygoteInit.main(ZygoteInit.java:659)
	dalvik.system.NativeStart.main(Native Method)
 */

/* 文件中的内容 

--------------------2014-1-15 上午8:08:12---------------------
com.example.skills.AppException
at com.example.skills.CustomApplication.onCreate(CustomApplication.java:22)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1004)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3368)
at android.app.ActivityThread.access$2200(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1031)
at android.os.Handler.dispatchMessage(Handler.java:130)
at android.os.Looper.loop(SourceFile:351)
at android.app.ActivityThread.main(ActivityThread.java:3814)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:538)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:659)
at dalvik.system.NativeStart.main(Native Method)

*/
